package com.ruoyi.security.service.impl;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 同步任务管理器
 * 用于管理分时数据同步任务的进度
 * 
 * @author yeoman
 * @date 2025/01/XX
 */
@Slf4j
@Component
public class SyncTaskManager {
    
    /**
     * 任务信息
     */
    @Data
    public static class TaskInfo {
        /**
         * 任务ID
         */
        private String taskId;
        
        /**
         * 证券代码
         */
        private String symbol;
        
        /**
         * 总天数
         */
        private int totalDays;
        
        /**
         * 已同步天数
         */
        private AtomicInteger syncedDays = new AtomicInteger(0);
        
        /**
         * 失败天数
         */
        private AtomicInteger failedDays = new AtomicInteger(0);
        
        /**
         * 已处理天数（无论成功还是失败）
         */
        private AtomicInteger processedDays = new AtomicInteger(0);
        
        /**
         * 任务状态：RUNNING, COMPLETED, FAILED
         */
        private String status = "RUNNING";
        
        /**
         * 错误信息
         */
        private String errorMessage;
        
        /**
         * 开始时间
         */
        private long startTime;
        
        /**
         * 完成时间
         */
        private Long endTime;
        
        /**
         * 当前正在同步的日期
         */
        private String currentDate;
    }
    
    /**
     * 任务存储（使用ConcurrentHashMap保证线程安全）
     */
    private final Map<String, TaskInfo> tasks = new ConcurrentHashMap<>();
    
    /**
     * 任务ID生成器
     */
    private final AtomicLong taskIdGenerator = new AtomicLong(0);
    
    /**
     * 创建新任务
     * 
     * @param symbol 证券代码
     * @param totalDays 总天数
     * @return 任务ID
     */
    public String createTask(String symbol, int totalDays) {
        String taskId = "sync-" + System.currentTimeMillis() + "-" + taskIdGenerator.incrementAndGet();
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setTaskId(taskId);
        taskInfo.setSymbol(symbol);
        taskInfo.setTotalDays(totalDays);
        taskInfo.setStartTime(System.currentTimeMillis());
        taskInfo.setStatus("RUNNING");
        
        tasks.put(taskId, taskInfo);
        log.info("创建同步任务，任务ID：{}，证券代码：{}，总天数：{}", taskId, symbol, totalDays);
        
        return taskId;
    }
    
    /**
     * 更新任务进度
     * 
     * @param taskId 任务ID
     * @param syncedDays 已同步天数
     * @param currentDate 当前正在同步的日期
     */
    public void updateProgress(String taskId, int syncedDays, String currentDate) {
        TaskInfo taskInfo = tasks.get(taskId);
        if (taskInfo != null) {
            taskInfo.getSyncedDays().set(syncedDays);
            taskInfo.setCurrentDate(currentDate);
        }
    }
    
    /**
     * 增加已同步天数
     * 
     * @param taskId 任务ID
     */
    public void incrementSyncedDays(String taskId) {
        TaskInfo taskInfo = tasks.get(taskId);
        if (taskInfo != null) {
            taskInfo.getSyncedDays().incrementAndGet();
        }
    }
    
    /**
     * 增加失败天数
     * 
     * @param taskId 任务ID
     */
    public void incrementFailedDays(String taskId) {
        TaskInfo taskInfo = tasks.get(taskId);
        if (taskInfo != null) {
            taskInfo.getFailedDays().incrementAndGet();
        }
    }
    
    /**
     * 增加已处理天数（无论成功还是失败）
     * 这个方法会检查任务是否完成
     * 
     * @param taskId 任务ID
     */
    public void incrementProcessedDays(String taskId) {
        TaskInfo taskInfo = tasks.get(taskId);
        if (taskInfo != null) {
            taskInfo.getProcessedDays().incrementAndGet();
            checkTaskCompleted(taskId, taskInfo);
        }
    }
    
    /**
     * 检查任务是否完成
     * 
     * @param taskId 任务ID
     * @param taskInfo 任务信息
     */
    private void checkTaskCompleted(String taskId, TaskInfo taskInfo) {
        if ("RUNNING".equals(taskInfo.getStatus())) {
            // 检查已处理天数是否达到总天数
            int processedDays = taskInfo.getProcessedDays().get();
            if (processedDays >= taskInfo.getTotalDays()) {
                taskInfo.setStatus("COMPLETED");
                taskInfo.setEndTime(System.currentTimeMillis());
                log.info("同步任务完成，任务ID：{}，成功：{}，失败：{}，总处理：{}", 
                        taskId, taskInfo.getSyncedDays().get(), taskInfo.getFailedDays().get(), processedDays);
            }
        }
    }
    
    /**
     * 标记任务失败
     * 
     * @param taskId 任务ID
     * @param errorMessage 错误信息
     */
    public void markTaskFailed(String taskId, String errorMessage) {
        TaskInfo taskInfo = tasks.get(taskId);
        if (taskInfo != null) {
            taskInfo.setStatus("FAILED");
            taskInfo.setErrorMessage(errorMessage);
            taskInfo.setEndTime(System.currentTimeMillis());
            log.error("同步任务失败，任务ID：{}，错误信息：{}", taskId, errorMessage);
        }
    }
    
    /**
     * 获取任务信息
     * 
     * @param taskId 任务ID
     * @return 任务信息
     */
    public TaskInfo getTask(String taskId) {
        return tasks.get(taskId);
    }
    
    /**
     * 删除任务（任务完成后可以清理）
     * 
     * @param taskId 任务ID
     */
    public void removeTask(String taskId) {
        tasks.remove(taskId);
        log.info("删除同步任务，任务ID：{}", taskId);
    }
    
    /**
     * 清理过期任务（超过1小时的任务）
     */
    public void cleanExpiredTasks() {
        long currentTime = System.currentTimeMillis();
        tasks.entrySet().removeIf(entry -> {
            TaskInfo taskInfo = entry.getValue();
            // 如果任务已完成或失败，且超过1小时，则清理
            if (("COMPLETED".equals(taskInfo.getStatus()) || "FAILED".equals(taskInfo.getStatus()))
                    && taskInfo.getEndTime() != null
                    && (currentTime - taskInfo.getEndTime()) > 3600000) {
                return true;
            }
            return false;
        });
    }
}

